from __future__ import print_function
from flask import Flask, Response
from pyzbar import pyzbar
from datetime import datetime

import cv2
from contextlib import contextmanager

app = Flask(__name__)

@contextmanager
def videoCapture():
  video_capture = cv2.VideoCapture(0)
  try:
    yield video_capture
  finally:
    video_capture.release()

@app.route('/stream')
def stream():
  return Response(gen(),
                  mimetype='multipart/x-mixed-replace; boundary=frame')


def gen():
  with videoCapture() as video_capture:
    while True:
      frame = get_frame(video_capture)
      yield (b'--frame\r\n'
             b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')


def get_frame(vc):
  _, frame = vc.read()
  process_frame(frame)
  ret, jpeg = cv2.imencode('.jpg', frame)

  return jpeg.tobytes()


def process_frame(frame):
  decoded_objs = decode(frame)
  draw_positions(frame, decoded_objs)


def decode(frame):
  decoded_objs = pyzbar.decode(frame, scan_locations=True)
  for decoded_obj in decoded_objs:
    print(datetime.now().strftime('%H:%M:%S.%f'))
    print('Type: ', decoded_obj.type)
    print('Data: ', decoded_obj.data.decode('utf8'))

  return decoded_objs


def draw_positions(frame, decoded_objs):
  for decoded_obj in decoded_objs:
    left, top, width, height = decoded_obj.rect
    frame = cv2.rectangle(frame,
                          (left, top),
                          (left + width, height + top),
                          (0, 255, 0), 2)


if __name__ == '__main__':
  app.run(host="0.0.0.0", debug=False, threaded=True)
